package com.zhang.server.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhang.server.common.Result;
import com.zhang.server.controller.dto.LoginDTO;
import com.zhang.server.controller.request.AdminPageRequest;
import com.zhang.server.controller.request.LoginRequest;
import com.zhang.server.controller.request.PasswordRequest;
import com.zhang.server.entity.Admin;
import com.zhang.server.ex.ServiceException;
import com.zhang.server.mapper.AdminMapper;
import com.zhang.server.service.IAdminService;
import com.zhang.server.utils.TokenUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class AdminService implements IAdminService {
    private static final String DEFAULT_PASS = "123"; // 默认密码
    private static final String PASS_SALT = "zhangsan"; // 盐值

    @Autowired
    AdminMapper adminMapper;

    @Override
    public List<Admin> list() {
        return adminMapper.list();
    }

    @Override
    public Object page(AdminPageRequest adminPageRequest) {
        // 将pageNum、pageSize作为参数传进方法
        PageHelper.startPage(adminPageRequest.getPageNum(), adminPageRequest.getPageSize());
        List<Admin> adminList = adminMapper.listByCondition(adminPageRequest);

        System.out.println(adminList.get(0));
        // 将查询结果放到这里,返回，就会自动分页
        return new PageInfo<>(adminList);
    }

    @Override
    public void save(Admin admin) {
        // 如果前端没传密码，那就设置一个默认密码
        if(StrUtil.isBlank(admin.getPassword())){
            admin.setPassword(DEFAULT_PASS);
        }

        // 密码 = MD5加密(明文密码 + 盐值)
        admin.setPassword(securePass(admin.getPassword() + PASS_SALT));

        try {
            adminMapper.save(admin);
        } catch (DuplicateKeyException e){
            throw new ServiceException("用户名重复");
        }
    }

    @Override
    public Admin getById(Integer id) {
        return adminMapper.getById(id);
    }

    @Override
    public void update(Admin admin) {
        adminMapper.update(admin);
    }

    @Override
    public void delete(Integer id) {
        adminMapper.delete(id);
    }

    @Override
    public LoginDTO login(LoginRequest loginRequest) {
        Admin admin = null;
        try {
            admin = adminMapper.getUsername(loginRequest.getUsername());
        }catch (Exception e){
            throw new ServiceException("用户名错误");
        }

        if(admin == null){
            throw new ServiceException("用户名或密码错误");
        }

        String securePassStr = securePass(loginRequest.getPassword() + PASS_SALT);
        if(!securePassStr.equals(admin.getPassword())){
            throw new ServiceException("用户名或密码错误");
        }

        if(!admin.isStatus()){
            throw new ServiceException("该用户已被禁用，请联系管理员");
        }

        LoginDTO loginDTO = new LoginDTO();

        // 如果两个对象有相同属性，将左边对应属性值映射给右边
        BeanUtils.copyProperties(admin, loginDTO);

        // 生成token
        String token = TokenUtils.genToken(String.valueOf(admin.getId()), admin.getPassword());
        loginDTO.setToken(token);

        return loginDTO;
    }

    public String securePass(String password){
        return SecureUtil.md5(password);
    }

    @Override
    public void updatePassword(PasswordRequest passwordRequest) {
        // 设置之前要对密码进行加密
        Admin admin = adminMapper.getUsernameAndPassword(new LoginRequest(passwordRequest.getUsername(), passwordRequest.getPassword()));

        passwordRequest.setUsername(admin.getUsername());
        passwordRequest.setPassword(admin.getPassword());
        passwordRequest.setNewPass(securePass(passwordRequest.getNewPass() + PASS_SALT));

        int count = adminMapper.updatePassword(passwordRequest);
        if(count <= 0){
            throw new ServiceException("修改密码失败");
        }
    }
}
